/**
 * Prompt Template Manager
 * 
 * 提示词模板管理器 - 负责模板的加载、存储、检索和应用
 */

import type {
  PromptTemplate,
  PromptCategory,
  PromptVariable,
  PromptTemplateVersion,
  PromptUsageStats,
} from '@/types/prompt';
import { BUILTIN_PROMPT_TEMPLATES } from './builtin-prompt-templates';

/**
 * 提示词模板管理器类
 */
export class PromptTemplateManager {
  private templates: Map<string, PromptTemplate> = new Map();
  private versions: Map<string, PromptTemplateVersion[]> = new Map();
  private stats: Map<string, PromptUsageStats> = new Map();

  constructor() {
    this.loadBuiltinTemplates();
    this.loadUserTemplates();
  }

  /**
   * 加载内置模板
   */
  private loadBuiltinTemplates(): void {
    BUILTIN_PROMPT_TEMPLATES.forEach(template => {
      this.templates.set(template.id, {
        ...template,
        usageCount: 0,
        createdAt: new Date(),
        updatedAt: new Date(),
      });
    });
  }

  /**
   * 加载用户自定义模板
   */
  private loadUserTemplates(): void {
    try {
      const stored = localStorage.getItem('cagent_prompt_templates');
      if (stored) {
        const templates = JSON.parse(stored) as PromptTemplate[];
        templates.forEach(template => {
          this.templates.set(template.id, template);
        });
      }
    } catch (error) {
      console.error('Failed to load user templates:', error);
    }
  }

  /**
   * 保存用户模板到 localStorage
   */
  private saveUserTemplates(): void {
    try {
      const userTemplates = Array.from(this.templates.values())
        .filter(t => !t.isBuiltin);
      localStorage.setItem('cagent_prompt_templates', JSON.stringify(userTemplates));
    } catch (error) {
      console.error('Failed to save user templates:', error);
    }
  }

  /**
   * 获取所有模板
   */
  getAllTemplates(): PromptTemplate[] {
    return Array.from(this.templates.values())
      .sort((a, b) => (b.usageCount || 0) - (a.usageCount || 0));
  }

  /**
   * 按类别获取模板
   */
  getTemplatesByCategory(category: PromptCategory): PromptTemplate[] {
    return Array.from(this.templates.values())
      .filter(t => t.category === category)
      .sort((a, b) => (b.usageCount || 0) - (a.usageCount || 0));
  }

  /**
   * 搜索模板
   */
  searchTemplates(query: string): PromptTemplate[] {
    const lowerQuery = query.toLowerCase();
    return Array.from(this.templates.values())
      .filter(t => 
        t.name.toLowerCase().includes(lowerQuery) ||
        t.description.toLowerCase().includes(lowerQuery) ||
        t.tags?.some(tag => tag.toLowerCase().includes(lowerQuery))
      )
      .sort((a, b) => (b.usageCount || 0) - (a.usageCount || 0));
  }

  /**
   * 获取单个模板
   */
  getTemplate(id: string): PromptTemplate | undefined {
    return this.templates.get(id);
  }

  /**
   * 添加或更新模板
   */
  saveTemplate(template: PromptTemplate): void {
    // 如果是更新，保存版本历史
    if (this.templates.has(template.id)) {
      const oldTemplate = this.templates.get(template.id)!;
      this.saveVersion(template.id, oldTemplate);
    }

    // 更新时间戳
    template.updatedAt = new Date();
    if (!template.createdAt) {
      template.createdAt = new Date();
    }

    this.templates.set(template.id, template);
    this.saveUserTemplates();
  }

  /**
   * 删除模板
   */
  deleteTemplate(id: string): boolean {
    const template = this.templates.get(id);
    if (!template || template.isBuiltin) {
      return false; // 不能删除内置模板
    }

    this.templates.delete(id);
    this.versions.delete(id);
    this.stats.delete(id);
    this.saveUserTemplates();
    return true;
  }

  /**
   * 应用模板 - 将变量替换为实际值
   */
  applyTemplate(
    templateId: string,
    variables: Record<string, string | number | boolean>
  ): string {
    const template = this.templates.get(templateId);
    if (!template) {
      throw new Error(`Template not found: ${templateId}`);
    }

    // 验证必填变量
    const missingVars = template.variables
      .filter(v => v.required && !variables[v.name])
      .map(v => v.name);

    if (missingVars.length > 0) {
      throw new Error(`Missing required variables: ${missingVars.join(', ')}`);
    }

    // 替换变量
    let result = template.template;
    for (const [name, value] of Object.entries(variables)) {
      const regex = new RegExp(`{{\\s*${name}\\s*}}`, 'g');
      result = result.replace(regex, String(value));
    }

    // 记录使用
    this.recordUsage(templateId);

    return result;
  }

  /**
   * 记录模板使用
   */
  recordUsage(templateId: string): void {
    const template = this.templates.get(templateId);
    if (template) {
      template.usageCount = (template.usageCount || 0) + 1;
      this.templates.set(templateId, template);
      this.saveUserTemplates();
    }

    // 更新统计
    const stat = this.stats.get(templateId) || {
      templateId,
      usageCount: 0,
      lastUsedAt: new Date(),
      averageRating: 0,
      ratingCount: 0,
    };
    stat.usageCount++;
    stat.lastUsedAt = new Date();
    this.stats.set(templateId, stat);
  }

  /**
   * 评分模板
   */
  rateTemplate(templateId: string, rating: number): void {
    const template = this.templates.get(templateId);
    if (!template) return;

    const stat = this.stats.get(templateId) || {
      templateId,
      usageCount: 0,
      lastUsedAt: new Date(),
      averageRating: 0,
      ratingCount: 0,
    };

    // 计算新的平均评分
    stat.averageRating = 
      (stat.averageRating * stat.ratingCount + rating) / (stat.ratingCount + 1);
    stat.ratingCount++;
    this.stats.set(templateId, stat);

    // 更新模板评分
    template.rating = stat.averageRating;
    this.templates.set(templateId, template);
    this.saveUserTemplates();
  }

  /**
   * 保存模板版本
   */
  private saveVersion(templateId: string, template: PromptTemplate): void {
    const versions = this.versions.get(templateId) || [];
    const version: PromptTemplateVersion = {
      version: versions.length + 1,
      template: template.template,
      variables: template.variables,
      createdAt: new Date(),
    };
    versions.push(version);
    this.versions.set(templateId, versions);
  }

  /**
   * 获取模板历史版本
   */
  getVersions(templateId: string): PromptTemplateVersion[] {
    return this.versions.get(templateId) || [];
  }

  /**
   * 恢复到指定版本
   */
  restoreVersion(templateId: string, version: number): boolean {
    const versions = this.versions.get(templateId);
    const template = this.templates.get(templateId);

    if (!versions || !template || version < 1 || version > versions.length) {
      return false;
    }

    const targetVersion = versions[version - 1];
    template.template = targetVersion.template;
    template.variables = targetVersion.variables;
    template.updatedAt = new Date();

    this.templates.set(templateId, template);
    this.saveUserTemplates();
    return true;
  }

  /**
   * 导出模板
   */
  exportTemplate(templateId: string): string {
    const template = this.templates.get(templateId);
    if (!template) {
      throw new Error(`Template not found: ${templateId}`);
    }
    return JSON.stringify(template, null, 2);
  }

  /**
   * 导入模板
   */
  importTemplate(jsonString: string): PromptTemplate {
    const template = JSON.parse(jsonString) as PromptTemplate;
    
    // 生成新 ID 以避免冲突
    template.id = `imported_${Date.now()}_${Math.random().toString(36).slice(2)}`;
    template.isBuiltin = false;
    template.createdAt = new Date();
    template.updatedAt = new Date();

    this.saveTemplate(template);
    return template;
  }

  /**
   * 获取热门模板
   */
  getPopularTemplates(limit: number = 10): PromptTemplate[] {
    return Array.from(this.templates.values())
      .sort((a, b) => (b.usageCount || 0) - (a.usageCount || 0))
      .slice(0, limit);
  }

  /**
   * 获取最近使用的模板
   */
  getRecentTemplates(limit: number = 10): PromptTemplate[] {
    const recentStats = Array.from(this.stats.values())
      .sort((a, b) => b.lastUsedAt.getTime() - a.lastUsedAt.getTime())
      .slice(0, limit);

    return recentStats
      .map(stat => this.templates.get(stat.templateId))
      .filter((t): t is PromptTemplate => t !== undefined);
  }

  /**
   * 验证模板语法
   */
  validateTemplate(template: string, variables: PromptVariable[]): {
    valid: boolean;
    errors: string[];
  } {
    const errors: string[] = [];

    // 检查变量占位符语法
    const placeholderRegex = /{{([^}]+)}}/g;
    const matches = template.matchAll(placeholderRegex);
    const usedVars = new Set<string>();

    for (const match of matches) {
      const varName = match[1].trim();
      usedVars.add(varName);

      // 检查变量是否已定义
      if (!variables.find(v => v.name === varName)) {
        errors.push(`未定义的变量: ${varName}`);
      }
    }

    // 检查未使用的变量
    const definedVars = new Set(variables.map(v => v.name));
    for (const varName of definedVars) {
      if (!usedVars.has(varName)) {
        errors.push(`变量未在模板中使用: ${varName}`);
      }
    }

    return {
      valid: errors.length === 0,
      errors,
    };
  }
}

// 单例实例
let instance: PromptTemplateManager | null = null;

/**
 * 获取提示词模板管理器实例
 */
export function getPromptTemplateManager(): PromptTemplateManager {
  if (!instance) {
    instance = new PromptTemplateManager();
  }
  return instance;
}

